import type { AxiosResponse } from 'axios';

import type {
  AuthorizationTokenDto,
  ChangePasswordDto,
  ConfirmEmailDto,
  ConfirmPhoneDto,
  EmailEditDto,
  LoginDto,
  OAuth2TokenDto,
  OrganizationNode,
  OrganizationTreeNode,
  PhoneEditDto,
  PhoneTokenDto,
  ProfileDto,
  ProfileEditDto,
  QRCoderTokenDto,
  RegisterDto,
  ResetPwdEmailDto,
  ResetPwdPhoneDto,
  SendEmailDto,
  TokenDto,
  UserLoginOutputDto,
} from './model';

import type { JsonWebToken, UserLoginInfoEx } from '#/auth';
import type { AjaxResult, ErrorMessageMode, PageData, PageRequest } from '#/request';

import { useMessage } from '@/hooks/web/useMessage';
import { request } from '@/utils/request/axios';

const { createMessage } = useMessage();

/** 身份认证服务URL枚举 */
enum Api {
  /** 用户名是否存在 */
  CheckUserNameExists = '/api/identity/checkUserNameExists',
  /** 用户Email是否存在 */
  CheckEmailExists = '/api/identity/checkEmailExists',
  /** 用户手机号是否存在 */
  CheckPhoneNumberExists = '/api/identity/checkPhoneNumberExists',
  /** 用户昵称是否存在 */
  CheckNickNameExists = '/api/identity/checkNickNameExists',

  /** 新用户注册URL */
  Register = '/api/identity/register',
  /** 登录URL（目前不开放该接口） */
  Login = '/api/identity/login',
  /** 获取身份认证令牌URL */
  Token = '/api/identity/token',
  /** 使用手机号获取身份认证令牌 */
  PhoneToken = '/api/identity/phoneToken',
  /** 使用授权码获取身份认证令牌 */
  AuthorizationToken = '/api/identity/authorizationToken',

  /** 获取登录二维码令牌 */
  GetQrCodeToken = '/api/identity/getQrCodeToken',
  /** 扫描登录二维码令牌 */
  ScanQrCodeToken = '/api/identity/scanQrCodeToken',
  /** 确认登录二维码令牌 */
  ConfirmQrCodeToken = '/api/identity/confirmQrCodeToken',

  /** OAuth2登录 */
  OAuth2 = '/api/identity/oauth2',
  /** OAuth2绑定 */
  OAuth2Bind = '/api/identity/oauth2bind',
  /** 第三方身份获取认证令牌 */
  OAuth2Token = '/api/identity/oauth2Token',
  /** 读取OAuth2登录信息 */
  ReadOAuth2 = '/api/identity/readOAuth2',
  /** 登录并绑定账号URL */
  LoginBind = '/api/identity/loginBind',
  /** 使用第三方账号一键登录URL */
  LoginOneKey = '/api/identity/loginOneKey',
  /** OAuth2绑定提交 */
  OAuth2BindCommit = '/api/identity/oAuth2BindCommit',
  /** 解除第三方登录 */
  RemoveOAuth2 = '/api/identity/removeOAuth2',

  /** 验证登录URL */
  Checklogin = '/api/identity/checkLogin',
  /** 用户登出URL */
  Logout = '/api/identity/logout',

  /** 获取在线用户信息 */
  Profile = '/api/identity/profile',
  /** 编辑用户资料 */
  ProfileEdit = '/api/identity/profileEdit',
  /** 修改密码 */
  ChangePassword = '/api/identity/changePassword',

  /** 获取组织机构节点 */
  GetOrganizationNode = '/api/identity/getOrganizationNode',
  /** 获取组织机构树 */
  GetOrganizationTree = '/api/identity/getOrganizationTree',
  /** 设置当前组织机构 */
  SetOrganization = '/api/identity/setOrganization',

  /** 发送激活注册邮件 */
  SendConfirmEmail = '/api/identity/sendConfirmEmail',
  /** 激活邮箱 */
  ConfirmEmail = '/api/identity/confirmEmail',
  /** 发送重置密码邮件 */
  SendResetPwdEmail = '/api/identity/sendResetPwdEmail',
  /** 根据电子邮箱重置登录密码 */
  ResetPwdByEmail = '/api/identity/resetPwdByEmail',
  /** 用户邮箱变更 */
  ChangeUserEmail = '/api/identity/changeUserEmail',

  /** 激活手机 */
  ConfirmPhone = '/api/identity/confirmPhone',
  /** 根据手机重置登录密码 */
  ResetPwdByPhone = '/api/identity/resetPwdByPhone',
  /** 用户手机变更 */
  ChangeUserPhone = '/api/identity/changeUserPhone',
}

// #region 用户名是否存在
/**
 * 用户名是否存在
 * @param userName 用户名
 * @param ignoreSelf 是否忽略自己
 * @param mode 错误消息模型
 */
export function checkUserNameExists(userName: string, ignoreSelf = true, mode: ErrorMessageMode = 'none') {
  if (!userName || userName === null || userName === '') {
    return Promise.resolve(false);
  }
  return request.get<boolean>(
    {
      url: Api.CheckUserNameExists,
      params: { userName, ignoreSelf },
    },
    {
      errorMessageMode: mode,
    },
  );
}
// #endregion
// #region 用户Email是否存在
/**
 * 用户Email是否存在
 * @param email 电子邮箱
 * @param ignoreSelf 是否忽略自己
 * @param mode 错误消息模型
 */
export function checkEmailExists(email: string, ignoreSelf = true, mode: ErrorMessageMode = 'none') {
  if (!email || email === null || email === '') {
    return Promise.resolve(false);
  }
  return request.get<boolean>(
    {
      url: Api.CheckEmailExists,
      params: { email, ignoreSelf },
    },
    {
      errorMessageMode: mode,
    },
  );
}
// #endregion
// #region 用户手机号是否存在
/**
 * 用户手机号是否存在
 * @param phoneNumber 手机号
 * @param ignoreSelf 是否忽略自己
 * @param mode 错误消息模型
 */
export function checkPhoneNumberExists(phoneNumber: string, ignoreSelf = true, mode: ErrorMessageMode = 'none') {
  if (!phoneNumber || phoneNumber === null || phoneNumber === '') {
    return Promise.resolve(false);
  }
  return request.get<boolean>(
    {
      url: Api.CheckPhoneNumberExists,
      params: { phoneNumber, ignoreSelf },
    },
    {
      errorMessageMode: mode,
    },
  );
}
// #endregion
// #region 用户昵称是否存在
/**
 * 用户昵称是否存在
 * @param nickName 用户昵称
 * @param ignoreSelf 是否忽略自己
 * @param mode 错误消息模型
 */
export function checkNickNameExists(nickName: string, ignoreSelf = true, mode: ErrorMessageMode = 'none') {
  if (!nickName || nickName === null || nickName === '') {
    return Promise.resolve(false);
  }
  return request.get<boolean>(
    {
      url: Api.CheckNickNameExists,
      params: { nickName, ignoreSelf },
    },
    {
      errorMessageMode: mode,
    },
  );
}
// #endregion

// #region 新用户注册
/**
 * 新用户注册
 * @param dto 用户注册信息DTO
 * @param mode 错误消息模型
 */
export function register(dto: RegisterDto, mode: ErrorMessageMode = 'modal') {
  return request.post(
    {
      url: Api.Register,
      params: dto,
    },
    {
      errorMessageMode: mode,
    },
  );
}
// #endregion

// #region 获取身份认证令牌
/**
 * 获取身份认证令牌
 * @param dto 身份认证令牌请求DTO
 * @param mode 错误消息模型
 */
export function token(dto: TokenDto, mode: ErrorMessageMode = 'modal') {
  return request.post<AjaxResult<JsonWebToken>>(
    {
      url: Api.Token,
      params: dto,
    },
    {
      errorMessageMode: mode,
    },
  );
}
// #endregion
// #region 使用手机号获取身份认证令牌
/**
 * 使用手机号获取身份认证令牌
 * @param dto 手机号令牌请求DTO
 * @param mode 错误消息模型
 */
export function phoneToken(dto: PhoneTokenDto, mode: ErrorMessageMode = 'modal') {
  return request.post<AjaxResult<JsonWebToken>>(
    {
      url: Api.PhoneToken,
      params: dto,
    },
    {
      errorMessageMode: mode,
    },
  );
}
// #endregion
// #region 使用授权码获取身份认证令牌
/**
 * 使用授权码获取身份认证令牌
 * @param dto 授权码身份认证令牌请求DTO
 * @param mode 错误消息模型
 */
export function authorizationToken(dto: AuthorizationTokenDto, mode: ErrorMessageMode = 'modal') {
  return request.post<AjaxResult<JsonWebToken>>(
    {
      url: Api.AuthorizationToken,
      params: dto,
    },
    {
      errorMessageMode: mode,
    },
  );
}
// #endregion

// #region 获取登录二维码令牌
/**
 * 获取登录二维码令牌
 * @param dto 二维码令牌DTO
 * @param mode 错误消息模型
 */
export function getQrCodeToken(dto: QRCoderTokenDto, mode: ErrorMessageMode = 'message') {
  return request.post(
    {
      url: Api.GetQrCodeToken,
      params: dto,
    },
    {
      errorMessageMode: mode,
    },
  );
}
// #endregion
// #region 扫描登录二维码令牌
/**
 * 扫描登录二维码令牌
 * @param dto 二维码令牌DTO
 * @param mode 错误消息模型
 */
export function scanQrCodeToken(dto: QRCoderTokenDto, mode: ErrorMessageMode = 'message') {
  return request.post(
    {
      url: Api.ScanQrCodeToken,
      params: dto,
    },
    {
      errorMessageMode: mode,
    },
  );
}
// #endregion
// #region 确认登录二维码令牌
/**
 * 确认登录二维码令牌
 * @param dto 二维码令牌DTO
 * @param mode 错误消息模型
 */
export function confirmQrCodeToken(dto: QRCoderTokenDto, mode: ErrorMessageMode = 'message') {
  return request.post(
    {
      url: Api.ConfirmQrCodeToken,
      params: dto,
    },
    {
      errorMessageMode: mode,
    },
  );
}
// #endregion

// #region OAuth2登录，跳转至登录页
/**
 * OAuth2登录，跳转至登录页
 * @param urlParams 授权地址参数
 */
export function oAuth2Login(urlParams: string) {
  const urlString = `${Api.OAuth2}?${urlParams}`;
  window.location.href = urlString;
}
// #endregion
// #region OAuth2绑定，跳转至登录页
/**
 * OAuth2绑定，跳转至登录页
 * @param urlParams 授权地址参数
 */
export function oAuth2Bind(urlParams: string) {
  const urlString = `${Api.OAuth2Bind}?${urlParams}`;
  createMessage.error(`OAuth2绑定功能暂不开放，请使用登录页三方登录后绑定处理模式！跳转页： ${urlString} 失败！`);

  // const name = 'oauth2bind'; //网页名称，可为空;
  // const iWidth = 600; //弹出窗口的宽度;
  // const iHeight = 600; //弹出窗口的高度;
  // //window.screen.height获得屏幕的高，window.screen.width获得屏幕的宽
  // const iTop = (window.screen.height - 30 - iHeight) / 2; //获得窗口的垂直位置;
  // const iLeft = (window.screen.width - 10 - iWidth) / 2; //获得窗口的水平位置;

  // const { BrowserWindow } = require('electron');
  // // const child = new BrowserWindow({ parent: top, modal: true, show: false });
  // const child = new BrowserWindow({ width: 600, height: 600, show: false });
  // child.loadURL(urlString);
  // child.once('ready-to-show', () => {
  //   child.show();
  // });

  // // 父窗口打开一个子窗口
  // window.open(
  //   urlString,
  //   name,
  //   'height=' +
  //     iHeight +
  //     ',,innerHeight=' +
  //     iHeight +
  //     ',width=' +
  //     iWidth +
  //     ',innerWidth=' +
  //     iWidth +
  //     ',top=' +
  //     iTop +
  //     ',left=' +
  //     iLeft +
  //     ',toolbar=no,menubar=no,scrollbars=auto,resizeable=no,location=no,status=no'
  // );

  // //  通过监听，父页面可以拿到子页面传递的token，父(前端页面)，子(小窗)
  // window.addEventListener(
  //   'message',
  //   function (e) {
  //     console.log(e.data);
  //   },
  //   false
  // );
}
// #endregion
// #region 第三方身份获取认证令牌
/**
 * 第三方身份获取认证令牌
 * @param dto 第三方身份获取TokenDTO
 * @param mode 错误消息模型
 */
export function oAuth2Token(dto: OAuth2TokenDto, mode: ErrorMessageMode = 'modal') {
  return request.post(
    {
      url: Api.OAuth2Token,
      params: dto,
    },
    {
      errorMessageMode: mode,
    },
  );
}
// #endregion
// #region 读取OAuth2登录信息
/**
 * 读取OAuth2登录信息
 * @param params 分页请求
 * @param mode 错误消息模型
 */
export function readOAuth2(params: PageRequest, mode: ErrorMessageMode = 'message') {
  return request.post<PageData<UserLoginOutputDto>>(
    {
      url: Api.ReadOAuth2,
      params,
    },
    {
      errorMessageMode: mode,
    },
  );
}
// #endregion
// #region 登录并绑定账号
/**
 * 登录并绑定账号
 * @param dto 第三方用户登录信息
 * @param mode 错误消息模型
 */
export function loginBind(dto: UserLoginInfoEx, mode: ErrorMessageMode = 'modal') {
  return request.post<AjaxResult<JsonWebToken>>(
    {
      url: Api.LoginBind,
      params: dto,
    },
    {
      errorMessageMode: mode,
    },
  );
}
// #endregion
// #region OAuth2绑定提交
/**
 * OAuth2绑定提交
 * @param dto 第三方用户登录信息
 * @param mode 错误消息模型
 */
export function oAuth2BindCommit(dto: UserLoginInfoEx, mode: ErrorMessageMode = 'message') {
  return request.post(
    {
      url: Api.OAuth2BindCommit,
      params: dto,
    },
    {
      errorMessageMode: mode,
    },
  );
}
// #endregion
// #region 使用第三方账号一键登录
/**
 * 使用第三方账号一键登录
 * @param dto 第三方用户登录信息
 * @param mode 错误消息模型
 */
export function loginOneKey(dto: UserLoginInfoEx, mode: ErrorMessageMode = 'modal') {
  return request.post<AjaxResult<JsonWebToken>>(
    {
      url: Api.LoginOneKey,
      params: dto,
    },
    {
      errorMessageMode: mode,
    },
  );
}
// #endregion
// #region 解除第三方登录
/**
 * 解除第三方登录
 * @param dto 第三方用户登录主键
 * @param mode 错误消息模型
 */
export function removeOAuth2(dto: (bigint | string)[], mode: ErrorMessageMode = 'message') {
  return request.post(
    {
      url: Api.RemoveOAuth2,
      params: dto,
    },
    {
      errorMessageMode: mode,
    },
  );
}
// #endregion

// #region 验证登录
/**
 * 验证登录
 * @param dto 登录信息DTO
 * @param mode 错误消息模型
 */
export async function checkLogin(dto: LoginDto, mode: ErrorMessageMode = 'none') {
  return request.post(
    {
      url: Api.Checklogin,
      params: dto,
    },
    {
      errorMessageMode: mode,
    },
  );
}
// #endregion
// #region 用户登出
/**
 * 用户登出
 * @param mode 错误消息模型
 */
export function logout(mode: ErrorMessageMode = 'message') {
  return request.post(
    {
      url: Api.Logout,
    },
    {
      errorMessageMode: mode,
    },
  );
}
// #endregion

// #region 获取在线用户信息
/**
 * 获取在线用户信息
 * @param mode 错误消息模型
 */
export function profile(mode: ErrorMessageMode = 'none') {
  return request.get<ProfileDto>(
    {
      url: Api.Profile,
    },
    {
      errorMessageMode: mode,
    },
  );
}
// #endregion
// #region 编辑用户资料
/**
 * 编辑用户资料
 * @param dto 用户资料编辑DTO
 * @param mode 错误消息模型
 */
export function profileEdit(dto: ProfileEditDto, mode: ErrorMessageMode = 'modal') {
  return request.post(
    {
      url: Api.ProfileEdit,
      params: dto,
    },
    {
      errorMessageMode: mode,
    },
  );
}
// #endregion
// #region 修改密码
/**
 * 修改密码
 * @param dto 修改密码信息
 * @param mode 错误消息模型
 */
export function changePassword(dto: ChangePasswordDto, mode: ErrorMessageMode = 'message') {
  return request.post(
    {
      url: Api.ChangePassword,
      params: dto,
    },
    {
      errorMessageMode: mode,
    },
  );
}
// #endregion

// #region 获取组织机构节点
/**
 * 获取组织机构节点
 * @param mode 错误消息模型
 */
export function getOrganizationNode(mode: ErrorMessageMode = 'none') {
  return request.get<AjaxResult<OrganizationNode[]>>(
    {
      url: Api.GetOrganizationNode,
    },
    {
      errorMessageMode: mode,
    },
  );
}
// #endregion
// #region 获取组织机构树
/**
 * 获取组织机构树
 * @param mode 错误消息模型
 */
export function getOrganizationTree(mode: ErrorMessageMode = 'none') {
  return request.get<AjaxResult<OrganizationTreeNode[]>>(
    {
      url: Api.GetOrganizationTree,
    },
    {
      errorMessageMode: mode,
    },
  );
}
// #endregion
// #region 设置当前组织机构
/**
 * 设置当前组织机构
 * @param organizationId 组织机构编号
 * @param mode 错误消息模型
 */
export function setOrganization(organizationId: string, mode: ErrorMessageMode = 'modal') {
  return request.post<AjaxResult<JsonWebToken>>(
    {
      // url: `${Api.SetOrganization}?organizationId=${organizationId}`,
      url: Api.SetOrganization,
      params: { organizationId },
    },
    {
      joinParamsToUrl: true,
      errorMessageMode: mode,
    },
  );
}
// #endregion

// #region 发送激活注册邮件
/**
 * 发送激活注册邮件
 * @param dto 激活邮箱信息
 * @param mode 错误消息模型
 */
export function sendConfirmEmail(dto: SendEmailDto, mode: ErrorMessageMode = 'modal') {
  return request.post(
    {
      url: Api.SendConfirmEmail,
      params: dto,
    },
    {
      errorMessageMode: mode,
    },
  );
}
// #endregion
// #region 确认邮箱
/**
 * 确认邮箱
 * @param dto 确认邮箱DTO
 * @param mode 错误消息模型
 */
export function confirmEmail(dto: ConfirmEmailDto, mode: ErrorMessageMode = 'none') {
  return request.post<AxiosResponse<AjaxResult>>(
    {
      url: Api.ConfirmEmail,
      params: dto,
    },
    {
      errorMessageMode: mode,
      isReturnNativeResponse: true,
    },
  );
}
// #endregion
// #region 发送重置密码邮件
/**
 * 发送重置密码邮件
 * @param dto 发送邮件信息
 * @param mode 错误消息模型
 */
export function sendResetPwdEmail(dto: SendEmailDto, mode: ErrorMessageMode = 'modal') {
  return request.post(
    {
      url: Api.SendResetPwdEmail,
      params: dto,
    },
    {
      errorMessageMode: mode,
    },
  );
}
// #endregion
// #region 根据电子邮箱重置登录密码
/**
 * 根据电子邮箱重置登录密码
 * @param dto 重置密码信息
 * @param mode 错误消息模型
 */
export function resetPwdByEmail(dto: ResetPwdEmailDto, mode: ErrorMessageMode = 'modal') {
  return request.post(
    {
      url: Api.ResetPwdByEmail,
      params: dto,
    },
    {
      errorMessageMode: mode,
    },
  );
}
// #endregion
// #region 用户邮箱变更
/**
 * 用户邮箱变更
 * @param dto 用户邮箱变更DTO
 * @param mode 错误消息模型
 */
export function changeUserEmail(dto: EmailEditDto, mode: ErrorMessageMode = 'message') {
  return request.post(
    {
      url: Api.ChangeUserEmail,
      params: dto,
    },
    {
      errorMessageMode: mode,
    },
  );
}
// #endregion

// #region 激活手机
/**
 * 激活手机
 * @param dto 确认手机DTO
 * @param mode 错误消息模型
 */
export function confirmPhone(dto: ConfirmPhoneDto, mode: ErrorMessageMode = 'modal') {
  return request.post(
    {
      url: Api.ConfirmPhone,
      params: dto,
    },
    {
      errorMessageMode: mode,
    },
  );
}
// #endregion
// #region 根据手机重置登录密码
/**
 * 根据手机重置登录密码
 * @param dto 重置密码信息
 * @param mode 错误消息模型
 */
export function resetPwdByPhone(dto: ResetPwdPhoneDto, mode: ErrorMessageMode = 'modal') {
  return request.post(
    {
      url: Api.ResetPwdByPhone,
      params: dto,
    },
    {
      errorMessageMode: mode,
    },
  );
}
// #endregion
// #region 用户手机变更
/**
 * 用户手机变更
 * @param dto 用户手机变更DTO
 * @param mode 错误消息模型
 */
export function changeUserPhone(dto: PhoneEditDto, mode: ErrorMessageMode = 'message') {
  return request.post(
    {
      url: Api.ChangeUserPhone,
      params: dto,
    },
    {
      errorMessageMode: mode,
    },
  );
}
// #endregion
